package cs2340.klondike.TaskFudger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import models.Category;
import models.Task;
import models.User;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.j256.ormlite.dao.ForeignCollection;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Toast;

/**
 * This class displays the google map onto the screen. In addition, it displays all the pinpoints at the locations of the tasks.
 * It also puts a pinpoint at the user's current locations and updates it as the user walks around.
 *
 * @author Shezil Kheraj
 */
public class LocationsActivity extends MapActivity implements LocationListener {
	MapView map;
	long start;
	long stop;
	MyLocationOverlay compass;
	MapController controller;
	int x,y;
	GeoPoint touchedPoint;
	GeoPoint point;
	Drawable d;
	List<Overlay> overlayList;
	LocationManager lm;
	String towers;
	int lat= 0 ;
    int lon = 0;
    HelloItemizedOverlay itemizedoverlay;
    
	/* (non-Javadoc)
	 * @see com.google.android.maps.MapActivity#onCreate(android.os.Bundle)
	 */
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map);
        map = (MapView)findViewById(R.id.mvMain);
        map.setBuiltInZoomControls(true);
        
        ForeignCollection<Task> tasksList = null;
        try {
      	tasksList = User.getCurrentUser().getTasks();
      	Log.d("DATABASE", "Got the tasks!");
      	Log.d("DATABASE", ""+tasksList.size());
        } catch (Exception e) {}
        
        d = getResources().getDrawable(R.drawable.ic_launcher);
        Drawable pinTodo = getResources().getDrawable(R.drawable.pin_todo);
        Drawable pinComplete = getResources().getDrawable(R.drawable.pin_complete);
        Drawable pinCurrent = getResources().getDrawable(R.drawable.location);
        Drawable overlay = getResources().getDrawable(R.drawable.info);
        //HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(d,this);
        
        itemizedoverlay = new HelloItemizedOverlay(overlay,this);
        
        Touchy touch = new Touchy();
        overlayList = map.getOverlays();
        overlayList.add(touch);
        compass = new MyLocationOverlay(LocationsActivity.this,map);
        overlayList.add(compass);
        controller = map.getController();
        controller.setZoom(15);
        
        //gets the longitude and latitude for all the current tasks
		if (tasksList != null) {
    		for (Task t : tasksList) {
    			try {
    			Log.d("TASKLOCATION", t.getLocation().toString());
    			} catch (Exception e) {
    				Log.d("NULLLOCATION", "Location was null");
    			}
    			if (t.getLocation() != null) {
	    			point = new GeoPoint(
	    					(int)(t.getLocation().getLatitude()*1E6),
	    					(int)(t.getLocation().getLongitude()*1E6));
	    			OverlayItem overlayItem = new OverlayItem(point,t.getTeaser(),t.getLocation().toString());
	    			CustomPinpoint custom = new CustomPinpoint(t.isCompleted() ? pinComplete : pinTodo,LocationsActivity.this);
	    			custom.insertPinpoint(overlayItem);
	    			overlayList.add(custom);
	    			itemizedoverlay.addOverlay(overlayItem);
	    			overlayList.add(itemizedoverlay);
    			}
    		}
		}
              
        //placing pinpoint at user's location
        lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Criteria crit = new Criteria();
        towers = lm.getBestProvider(crit, false);
        Location location = lm.getLastKnownLocation(towers);
        //puts a pinpoint at the user's current location
        if(location != null) {
	        lat = (int)(location.getLatitude()*1E6);
			lon = (int)(location.getLongitude()*1E6);
			GeoPoint ourLocation = new GeoPoint(lat, lon);
		    OverlayItem overlayItem = new OverlayItem(ourLocation,"My Location", null);
		  	CustomPinpoint custom = new CustomPinpoint(pinCurrent,LocationsActivity.this);
		  	custom.insertPinpoint(overlayItem);
		  	overlayList.add(custom);
		  	controller.animateTo(ourLocation);
		  	itemizedoverlay.addOverlay(overlayItem);
			overlayList.add(itemizedoverlay);
        }
        else {
    	  Toast.makeText(LocationsActivity.this, "Couldn't get provider", Toast.LENGTH_SHORT).show();
        } 
    }

	/* (non-Javadoc)
	 * @see com.google.android.maps.MapActivity#onPause()
	 */
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		compass.disableCompass();
		super.onPause();
		lm.removeUpdates(this);
	}

	/* (non-Javadoc)
	 * @see com.google.android.maps.MapActivity#onResume()
	 */
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		compass.enableCompass();
		super.onResume();	
		lm.requestLocationUpdates(towers, 500, 1, this);
	}

	/* (non-Javadoc)
	 * @see com.google.android.maps.MapActivity#isRouteDisplayed()
	 */
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	
	/**
	 * This is a touchy class that reads the coordinates when the user touches the screen for more than 1.5 seconds.
	 * When the user touches a point on the screen for more than 1.5 seconds, a pop up appears with the options to display 
	 * address of the point touched, insert pinpoint at this location, or change the current view from satellite to street and vise-versa.
	 * 
	 * @author Shezil Kheraj
	 */
	class Touchy extends Overlay {
		@SuppressWarnings("deprecation")
		public boolean onTouchEvent(MotionEvent e, MapView m) {
			if(e.getAction() == MotionEvent.ACTION_DOWN) {
				start = e.getEventTime();
				x=(int)e.getX();
				y=(int)e.getY();
				touchedPoint = map.getProjection().fromPixels(x, y);
			}
			if(e.getAction() == MotionEvent.ACTION_UP) {
				stop = e.getEventTime();
			}
			if(stop - start > 1500) { // one and a half second
				AlertDialog alert = new AlertDialog.Builder(LocationsActivity.this).create();
				alert.setMessage("Message");
				//places a pinpoint at the location you touched
				alert.setButton("Place a pinpoint", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						OverlayItem overlayItem = new OverlayItem(touchedPoint,"Touched","Here");
						CustomPinpoint custom = new CustomPinpoint(d,LocationsActivity.this);
						custom.insertPinpoint(overlayItem);
						overlayList.add(custom);					
						//HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(d,this);
						itemizedoverlay.addOverlay(overlayItem);
						overlayList.add(itemizedoverlay);
					}
				});
				//Displays the address of the location you touched
				alert.setButton2("Get Address", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						Geocoder geocoder = new Geocoder(getBaseContext(),Locale.getDefault());
						try {
								List<Address> address = geocoder.getFromLocation(touchedPoint.getLatitudeE6() / 1E6, touchedPoint.getLongitudeE6() / 1E6, 1);
								if(address.size() >0) {
									String display = "";
									for(int i = 0; i<address.get(0).getMaxAddressLineIndex(); i++) {
										display += address.get(0).getAddressLine(i)+"\n";
									}
									Toast t = Toast.makeText(getBaseContext(), display, Toast.LENGTH_LONG);
									t.show();
								}
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}finally{
							
						}
					}
				});
				//Allows the user to switch between sat view and street view
				alert.setButton3("Toggle View", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						if(map.isSatellite()) {
							map.setSatellite(false);
							map.setStreetView(true);
						}else {
							map.setStreetView(false);
							map.setSatellite(true);
						}
					}
				});
				alert.show();
				return true;
			}
			return false;
		}
	}
	
	/* (non-Javadoc)
	 * @see android.location.LocationListener#onLocationChanged(android.location.Location)
	 */
	@Override
	//If the user moves... it updates the location of the user
	public void onLocationChanged(Location l) {
		// TODO Auto-generated method stub
		lat = (int)(l.getLatitude()*1E6);
		lon = (int)(l.getLongitude()*1E6);
		GeoPoint ourLocation = new GeoPoint(lat, lon);
        OverlayItem overlayItem = new OverlayItem(ourLocation,"My Location", "Me");
  	  	CustomPinpoint custom = new CustomPinpoint(d,LocationsActivity.this);
  	  	custom.insertPinpoint(overlayItem);
  	  	overlayList.add(custom);
  	  	//HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(d,this);
  	  	itemizedoverlay.addOverlay(overlayItem);
		overlayList.add(itemizedoverlay);
	}

	/* (non-Javadoc)
	 * @see android.location.LocationListener#onProviderDisabled(java.lang.String)
	 */
	@Override
	public void onProviderDisabled(String arg0) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see android.location.LocationListener#onProviderEnabled(java.lang.String)
	 */
	@Override
	public void onProviderEnabled(String arg0) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see android.location.LocationListener#onStatusChanged(java.lang.String, int, android.os.Bundle)
	 */
	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO Auto-generated method stub
		
	}
}






